<template>
  <div class="uploader ui flex column item one">
    <slot :files="files" :file-list="fileList" :started="started">
      <uploader-unsupport></uploader-unsupport>
      <uploader-drop>
        <p>Drop files here to upload or</p>
        <uploader-btn>select files</uploader-btn>
        <uploader-btn :directory="true">select folder</uploader-btn>
      </uploader-drop>
      <uploader-list></uploader-list>
    </slot>
  </div>
</template>

<script>
import Uploader from 'simple-uploader.js'
import { kebabCase } from '../common/utils'
import UploaderBtn from './btn.vue'
import UploaderDrop from './drop.vue'
import UploaderUnsupport from './unsupport.vue'
import UploaderList from './list.vue'
import UploaderFiles from './files.vue'
import UploaderFile from './file.vue'

const COMPONENT_NAME = 'uploader'
const FILE_ADDED_EVENT = 'fileAdded'
const FILES_ADDED_EVENT = 'filesAdded'

export default {
    name: COMPONENT_NAME,
    props: {
        options: {
            type: Object,
            default() {
                return {}
            }
        },
        autoStart: {
            type: Boolean,
            default: true
        },
        fileStatusText: {
            type: Object,
            default() {
                return {
                    success: '成功',
                    error: '失败',
                    uploading: '上传中',
                    paused: '暂停',
                    waiting: '等待上传'
                }
            }
        }
    },
    data() {
        return {
            started: false,
            files: [],
            fileList: []
        }
    },
    methods: {
        uploadStart() {
            this.started = true
        },
        fileAdded(file) {
            this.$emit(kebabCase(FILE_ADDED_EVENT), file)
            if (file.ignored) {
                // is ignored, filter it
                return false
            }
        },
        filesAdded(files, fileList) {
            this.$emit(kebabCase(FILES_ADDED_EVENT), files, fileList)
            if (files.ignored || fileList.ignored) {
                // is ignored, filter it
                return false
            }
        },
        fileRemoved(file) {
            this.files = this.uploader.files
            this.fileList = this.uploader.fileList
        },
        filesSubmitted(files, fileList) {
            this.files = this.uploader.files
            this.fileList = this.uploader.fileList
            if (this.autoStart) {
                this.uploader.upload()
            }
        },
        allEvent(...args) {
            const name = args[0]
            if (name === FILE_ADDED_EVENT || name === FILES_ADDED_EVENT) {
                return
            }
            args[0] = kebabCase(name)
            this.$emit.apply(this, args)
        }
    },
    created() {
        const uploader = new Uploader(this.options)
        this.uploader = uploader
        this.uploader.fileStatusText = this.fileStatusText
        uploader.on('catchAll', this.allEvent)
        uploader.on('uploadStart', this.uploadStart)
        uploader.on(FILE_ADDED_EVENT, this.fileAdded)
        uploader.on(FILES_ADDED_EVENT, this.filesAdded)
        uploader.on('fileRemoved', this.fileRemoved)
        uploader.on('filesSubmitted', this.filesSubmitted)
    },
    destroyed() {
        const uploader = this.uploader
        uploader.off('catchAll', this.allEvent)
        uploader.off('uploadStart', this.uploadStart)
        uploader.off(FILE_ADDED_EVENT, this.fileAdded)
        uploader.off(FILES_ADDED_EVENT, this.filesAdded)
        uploader.off('fileRemoved', this.fileRemoved)
        uploader.off('filesSubmitted', this.filesSubmitted)
        this.uploader = null
    },
    components: {
        UploaderBtn,
        UploaderDrop,
        UploaderUnsupport,
        UploaderList,
        UploaderFiles,
        UploaderFile
    }
}
</script>

<style>
.uploader {
    position: relative;
}
</style>
